Array.prototype.myReduce = function (fn, initialValue) {
    var arr = this,
        len = arr.length,
        item
    for (var i = 0; i < len; i++) {
        initialValue = fn(initialValue, item, i, arr)
    }
    return initialValue
}
Array.prototype.myReduceRight = function (fn, initialValue) {
    var arr = this,
        len = arr.length,
        item
    for (var i = len - 1; i >= 0; i--) {
        initialValue = fn(initialValue, item, i, arr)
    }
    return initialValue
}

function judgeType(obj) {
    const toString = Object.prototype.toString;
    const map = {
        "[object Boolean]": "boolean",
        "[object Number]": "number",
        "[object String]": "string",
        "[object Function]": "function",
        "[object Array]": "array",
        "[object Date]": "date",
        "[object RegExp]": "regExp",
        "[object Undefined]": "undefined",
        "[object Null]": "null",
        "[object Object]": "object",
    };
    if (obj instanceof Element) {
        return "element";
    }
    return map[toString.call(obj)];
}
/**
 * @description 深克隆
 * @param {Object} data 
 */
function deepClone(data) {
    const type = this.judgeType(data);
    let obj = null;
    if (type == "array") {
        obj = [];
        for (let i = 0; i < data.length; i++) {
            obj.push(this.deepClone(data[i]));
        }
    } else if (type == "object") {
        obj = {};
        for (let key in data) {
            if (data.hasOwnProperty(key)) {
                obj[key] = this.deepClone(data[key]);
            }
        }
    } else {
        return data;
    }
    return obj;
}